package com.lww.feature.test.reflectionIntrospector;

import org.junit.Test;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;

/**
 * User: yian
 * Date: 2017/5/6
 * 反射只有在框架中才有意义，前提是根据框架的约定写类或者根据框架的约定告诉框架一些你的类的信息。
 */
public class test {

    @Test
    public void reflection() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Class<?> aClass = Class.forName("com.lww.feature.test.reflectionIntrospector.JavaBean");
        Object o = aClass.newInstance();
    }

    /**
     * 内省就是产品化了简单javabean的解析，用于表单映射，mybatis的表映射等。
     * 把能公用的地方共抽出来了，但是不能公用的地方是不用公用,比如表单提交时
     * 表单中的字段名和bean中的一一对应，并且类型也对应还需要人工保证的，mybatis也类似。
     * @throws ClassNotFoundException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    @Test
    public void introspector() throws ClassNotFoundException, IllegalAccessException, InstantiationException, IntrospectionException, InvocationTargetException {
        Class<?> aClass = Class.forName("com.lww.feature.test.reflectionIntrospector.JavaBean");
        Object o = aClass.newInstance();
        BeanInfo bi= Introspector.getBeanInfo(aClass, Object.class);
        PropertyDescriptor[] propertyDescriptors = bi.getPropertyDescriptors();
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            switch (propertyDescriptor.getName()) {
                case "p1":
                    propertyDescriptor.getWriteMethod().invoke(o, "p1");
                    break;
                case "p2":
                    propertyDescriptor.getWriteMethod().invoke(o, 5);
                    break;
                case "p3":
                    propertyDescriptor.getWriteMethod().invoke(o, new Integer(1));
                    break;
                default:
                    break;
            }
        }
        System.out.println(o);
    }
}
